package monitoring.sla.throughput;

import java.util.Vector;

import monitoring.sla.Transition;
import monitoring.utility.StaticFields;

import store.hibernate.Event;

public class ThroughputManager {
	private String init_st;
	private String end_st;
	private String cur_st;
	private Vector<Long> t;
	//private Vector<Character> act;
	private int cur_index,count;
	private int numStates;
	private Vector<Transition> transitions; // Vector of Transition object
	private long xreal;

	public ThroughputManager(int numStates, String init_st, String end_st) {
		this.init_st = init_st;
		this.end_st = end_st;
		cur_st = null;
		this.numStates=numStates;
		t = new Vector<Long>();
		//act = new Vector<Character>();
		cur_index = 0;
		count = 0;
		xreal = 0;
		transitions= new Vector<Transition>();
	//	System.out.println("AUTOMA: numStates-"+numStates+" init_st-"+init_st+" end_st-"+end_st);
	}

        public void addTransition(Transition t) {
    	transitions.addElement(t);
    //	t.printTransition();
        }


        public void makeTrans(Event event) {
        	//filtro le prime count richieste
        	if(event.getDirection()==StaticFields.INB_CHAR){
        		if ( count < numStates - 1 ) {
        			//	act.add(event.getDirection());
        			t.add(event.getTimestamp());
        			count++;
        		} else {
        			//	act.set(cur_index,event.getDirection());
        			t.set(cur_index,event.getTimestamp());
        			cur_index++;
        			if ( cur_index == numStates - 1 ) {
        				cur_index = 0;
        			}
        		}
        		if ( count >= numStates - 1 ) {
        			int myplace = 0;
        			myplace = cur_index;
        			for (int i=0; i < numStates-1; i++ ) {
        				int whichone = (myplace+i) % (numStates-1);
        				int res = intMakeTrans((t.elementAt(whichone)));
        				if ( res == 1 ) {
        					System.out.println("THROUGHPUT VIOLATION DETECTED. This is the trace of the violation:");
        					Long first=(long)0;
        					for ( int j=0; j<numStates-1; j++ ) {
        						int place = (myplace+j) % (numStates-1);
        						System.out.println("T = "+t.elementAt(place));
								if(j==0)
        							first=t.elementAt(place);
								if(j==numStates-2){
									long diff=t.elementAt(place)-first;
									System.out.println("diff="+diff);
								}
        					}
        				}
        			}
        		}
        	}
        }

        public int intMakeTrans(long time) {
        	boolean done = false;
        	long x = time - xreal;

        	if ( cur_st == null ) {
        		cur_st = init_st;
        	}

        	// Create an evolution for each condition
        	//boolean snd=true;
        	boolean third=true;

        	for (int j=0; j < transitions.size(); j++ ) {
        		Transition t = (Transition) transitions.elementAt(j);
        		// Condition for evolution
        		if (  ( done == false ) && cur_st.equals(t.getSource())){
        			/*if ( t.getLabels() != null ) {
					Vector<Character> tmpv = t.getLabels();
					snd=false;
					int i=0;
					while ((i < tmpv.size()) && !snd) {
						snd=(action == tmpv.elementAt(i));
						i++;
					}*/
        			if (t.getGuard() >0 ) {
        				if((x < t.getGuard()) && (x!=0)) {
        					//System.out.println("VIOLATION "+time+" "+xreal);
        					third=true;
        				}
        				else
        					third=false;
        			}
        			if(third)  {   
        				done = true;
        				cur_st = t.getTarget();        		
        				Vector<String> c2reset = t.getCResets();
        				if ( c2reset != null && c2reset.size()>0) 
        					xreal = time;
        			}
        		}

        	}
        	if ( cur_st.equals(end_st) ) { 
        		cur_st = null;
        		return 1;
        	}
        	if ( done == false ) {
        		cur_st = null;
        		xreal = 0;
        		return -1;
        	}
        	return 0;
        }

}
